<?php

namespace StarCloud\Library\Sdk\KsOpen;

class KsOpen extends Client
{
    private $app_id;
    private $secret;
    private $callback;
    protected $baseUri = "https://open.kuaishou.com";

    const OAUTH_PREFIX = "https://open.kuaishou.com";
    const OAUTH_AUTHORIZE_URL = "/oauth2/authorize?";
    const OAUTH_TOKEN_URL = '/oauth2/access_token?';
    const OAUTH_REFRESH_URL = '/oauth2/refresh_token?';

    const QRCODE_URL = "/oauth2/qr_code?";

    public function __construct($config)
    {
        $this->app_id = $config['app_id'];
        $this->secret = $config['secret'];
        $this->callback = $config['callback'];
    }

    /**
     * oauth 授权跳转接口
     * @param string $callback 回调URI
     * @return string
     */
    public function getOauthRedirect($callback, $state='', $scope='snsapi_userinfo')
    {
        return self::OAUTH_PREFIX.self::OAUTH_AUTHORIZE_URL.'app_id='.$this->app_id.'&redirect_uri='.urlencode($callback).'&response_type=code&scope='.$scope.'&state='.$state.'#wechat_redirect';
    }

    public function getOauthQrcode()
    {
        return self::OAUTH_PREFIX.self::QRCODE_URL.'app_id=' .$this->app_id .'&scope=user_info,user_video_publish&response_type=code&redirect_uri='.$this->callback.'&state=your_state&qr_size=300';
    }

    /**
     * 通过code获取Access Token
     * @return array {access_token,expires_in,refresh_token,openid,scope}
     */
    public function getOauthAccessToken()
    {
        $code = isset($_GET['code'])?$_GET['code']:'';
        if (!$code) {
            return false;
        }
        $result = $this->http_get(self::OAUTH_PREFIX.self::OAUTH_TOKEN_URL.'app_id='.$this->app_id.'&app_secret='.$this->secret.'&code='.$code.'&grant_type=authorization_code');
        if ($result) {
            $json = json_decode($result, true);
            if (isset($json['result']) && $json['result'] == 1) {
                $this->user_token = $json['access_token'];
                return $json;
            }
            return false;
        }
        return false;
    }

     /**
      * 刷新access token并续期
      * @param string $refresh_token
      * @return boolean|mixed
      */
    public function getOauthRefreshToken($refresh_token)
    {
        $result = $this->http_get(self::OAUTH_PREFIX.self::OAUTH_REFRESH_URL.'app_id='.$this->app_id.'&app_secret='.$this->secret.'&grant_type=refresh_token&refresh_token='.$refresh_token);
        if ($result) {
            $json = json_decode($result, true);
            if (isset($json['result']) && $json['result'] == 1) {
                $this->user_token = $json['access_token'];
                return $json;
            }
            return false;
        }
        return false;
    }

    /**
     * 发起上传
     *
     * @param string $access_token
     * @return array
     */
    public function startUpload(string $access_token)
    {
        $query = [
            'app_id' => $this->app_id,
            'access_token' => $access_token,
        ];

        $response = $this->httpPostJson($this->baseUri . '/openapi/photo/start_upload', $query);

        return self::resource($response);
    }

    /**
     * 直接上传
     *
     * @param string $endpoint
     * @param string $upload_token
     * @param string $video_path
     * @return array
     */
    public function uploadVideo(string $endpoint, string $upload_token, string $video_path)
    {
        $query = [
            'upload_token' => $upload_token,
        ];

        $response = $this->httpPostUploadVideo('http://' . $endpoint . '/api/upload/multipart?', $query, $video_path);

        return self::resource($response);
    }

    /**
     * 发布视频
     *
     * @param string $access_token
     * @param string $upload_token
     * @param string $cover_path 封面图地址
     * @param string $caption 视频标题
     * @return array
     */
    public function publishVideo(string $access_token, string $upload_token, string $cover_path, string $caption)
    {

        $query = [
            'app_id' => $this->app_id,
            'access_token' => $access_token,
            'upload_token' => $upload_token,
        ];

        $multipart = [
            [
                // 封面图 必填 <10mb
                'name' => 'cover',
                'contents' => fopen($cover_path, 'r'),
            ],
            [
                'name' => 'caption',
                'contents' => $caption,
            ],
        ];

        $response = $this->httpPostMultipart(
            $this->baseUri . '/openapi/photo/publish',
            $query,
            $multipart
        );

        return self::resource($response);
    }

    /**
     * 合并操作发布视频
     *
     * @param string $access_token
     * @param string $video_path
     * @param string $cover_path
     * @param string $caption
     * @return array
     */
    public function publishChannel(string $access_token, string $video_path, string $cover_path, string $caption)
    {
        $start_upload = $this->startUpload($access_token);

        if ($start_upload['result'] != 1) {
            throw new \Exception('发起上传失败');
        }

        $upload_video = $this->uploadVideo($start_upload['endpoint'], $start_upload['upload_token'], $video_path);

        if ($upload_video['result'] === 1) {
            return $this->publishVideo($access_token, $start_upload['upload_token'], $cover_path, $caption);
        } else {
            throw new \Exception('上传视频发生错误');
        }
    }

    /**
     * 查询视频列表
     *
     * @param string $access_token
     * @param string $cursor
     * @param integer $count
     * @return array
     */
    public function photoList(string $access_token, string $cursor = null, int $count = 200)
    {
        $query = [
            'app_id' => $this->app_id,
            'access_token' => $access_token,
            'cursor' => $cursor,
            'count' => $count,
        ];

        $response = $this->httpGet($this->baseUri . '/openapi/photo/list', array_filter($query));

        return self::resource($response);
    }

    /**
     * 视频信息查询
     *
     * @param string $access_token
     * @param string $photo_id
     * @return array
     */
    public function photoInfo(string $access_token, string $photo_id)
    {
        $query = [
            'app_id' => $this->app_id,
            'access_token' => $access_token,
            'photo_id' => $photo_id,
        ];

        $response = $this->httpGet($this->baseUri . '/openapi/photo/info', $query);

        return self::resource($response);
    }


    // 挂载小程序
    public function plcBind($accessToken, $photoId, $plc_mp_app_id, $plc_title, $plc_mp_path)
    {
        $query = [
            'access_token' => $accessToken,
            'app_id' => $this->app_id,
            'photo_id' => $photoId,
            'plc_mp_app_id' => $plc_mp_app_id,
            'plc_title' => $plc_title,
            'plc_mp_path' => $plc_mp_path
        ];

        $response = $this->http_post($this->baseUri . '/openapi/photo/mp_plc/bind', $query);

        return json_decode($response, true);
    }

    public function getPlcMembers()
    {

    }

    /**
     * GET 请求
     * @param string $url
     */
    private function http_get($url)
    {
        $oCurl = curl_init();
        if (stripos($url, "https://")!==false) {
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        if (intval($aStatus["http_code"])==200) {
            return $sContent;
        } else {
            return false;
        }
    }

    /**
     * POST 请求
     * @param string $url
     * @param array $param
     * @param boolean $post_file 是否文件上传
     * @return string content
     */
    private function http_post($url, $param, $header=[], $post_file=false)
    {
        $oCurl = curl_init();
        if (stripos($url, "https://")!==false) {
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) {
            $is_curlFile = true;
        } else {
            $is_curlFile = false;
            if (defined('CURLOPT_SAFE_UPLOAD')) {
                curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false);
            }
        }
        if (is_string($param)) {
            $strPOST = $param;
        } elseif ($post_file) {
            if ($is_curlFile) {
                foreach ($param as $key => $val) {
                    if (substr($val, 0, 1) == '@') {
                        $param[$key] = new \CURLFile(realpath(substr($val, 1)));
                    }
                }
            }
            $strPOST = $param;
        } else {
            $aPOST = [];
            foreach ($param as $key=>$val) {
                $aPOST[] = $key."=".urlencode($val);
            }
            $strPOST =  join("&", $aPOST);
        }
        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($oCurl, CURLOPT_POST, true);
        curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
        curl_setopt($oCurl,CURLOPT_HTTPHEADER,$header);

        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        if (intval($aStatus["http_code"])==200) {
            return $sContent;
        } else {
            return false;
        }
    }
}